#include "SPI0.h"
#include <stdio.h>


void SPI0_init() {
    uint32_t spix = SPI0;
    uint32_t spix_rcu = RCU_SPI0;
    /************************** GPIO **********************/
    // sclk
    rcu_periph_clock_enable(CLK_RCU);
    gpio_mode_set(CLK_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, CLK_PIN);
    gpio_output_options_set(CLK_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, CLK_PIN);
    gpio_af_set(CLK_PORT, CLK_AF, CLK_PIN);

    // mosi
    rcu_periph_clock_enable(MOSI_RCU);
    gpio_mode_set(MOSI_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MOSI_PIN);
    gpio_output_options_set(MOSI_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, MOSI_PIN);
    gpio_af_set(MOSI_PORT, MOSI_AF, MOSI_PIN);

    // miso
    rcu_periph_clock_enable(MISO_RCU);
    gpio_mode_set(MISO_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MISO_PIN);
    gpio_output_options_set(MISO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, MISO_PIN);
    gpio_af_set(MISO_PORT, MISO_AF, MISO_PIN);
    gpio_bit_set(MISO_PORT, MISO_PIN);

    /************************** SPI **********************/
    rcu_periph_clock_enable(spix_rcu);
    spi_i2s_deinit(spix);

    spi_parameter_struct sps;
    spi_struct_para_init(&sps);
    sps.device_mode = SPI_MASTER; //主设备
    sps.frame_size = SPI_FRAMESIZE_8BIT;//每次传输的数据长度为 8 位。
    sps.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; //表示时钟空闲时为低电平，数据在时钟的第一个边沿（上升沿）采样。
    sps.nss = SPI_NSS_SOFT;//设置 NSS（片选信号）的控制方式为软件控制。在软件控制模式下，主设备可以通过程序来控制 NSS 信号的电平。
    sps.prescale = SPI_PSC_32;//设置 SPI 时钟的预分频系数为 32
    sps.endian = SPI_ENDIAN_MSB;//设置数据传输的字节顺序为大端模式。在大端模式下，数据的最高有效位（MSB）先传输。
    spi_init(spix, &sps);
    //spi_nss_internal_high(spix);
    spi_enable(spix);
}

void SPI0_write_byte(uint8_t data) {
    while (RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {};
    spi_i2s_data_transmit(SPI0, data);
    while (RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {};
    spi_i2s_data_receive(SPI0);
}

uint8_t SPI0_read_byte() {
    while (RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {};
    spi_i2s_data_transmit(SPI0, 0x00);
    while (RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {};
    return spi_i2s_data_receive(SPI0);
}